public class Kernel
{

	private Population base;
	private PopulationContainer circularCode;
	private PopulationContainer circularCodeSelfComplementary;
	private PopulationContainer circularCodeMaximaux;
	private PopulationContainer circularCodeMaximauxSelfComplementary;

	public PopulationContainer getCircularCodeSelfComplementary()
	{
		return circularCodeSelfComplementary;
	}

	public void setCircularCodeSelfComplementary(
			PopulationContainer circularCodeSelfComplementary)
	{
		this.circularCodeSelfComplementary = circularCodeSelfComplementary;
	}

	public PopulationContainer getCircularCodeMaximauxSelfComplementary()
	{
		return circularCodeMaximauxSelfComplementary;
	}

	public void setCircularCodeMaximauxSelfComplementary(
			PopulationContainer circularCodeMaximauxSelfComplementary)
	{
		this.circularCodeMaximauxSelfComplementary = circularCodeMaximauxSelfComplementary;
	}

	public Kernel()
	{
		super();
		// On genere l'ensemble "base" qui sera l'ensemble de toutes les
		// combinaisons dans A
		this.base = new Population();
		this.base.PopulationBase();
		this.circularCode = new PopulationContainer();
		this.circularCodeSelfComplementary = new PopulationContainer();
		this.circularCodeMaximaux = new PopulationContainer();
		this.circularCodeMaximauxSelfComplementary = new PopulationContainer();
	}

	public Population getBase()
	{
		return base;
	}

	private Population baseForCCL()
	{

		Population tmp = new Population();
		for (int i = 0; i < base.size(); i++)
		{
			if (base.get(i).permute().isGreaterThan(base.get(i)) != 0
					&& !tmp.hasMemberOf(base.get(i))
					&& !tmp.hasMemberOf(base.get(i).permute()))
			{
				tmp.add(new Nucleotide(base.get(i)));
			}
		}
		return tmp;
	}

	public int[] CCL()
	{
		// circularCode = new PopulationContainer();
		circularCode.clear();
		int result[] = new int[6];
		Population ccl_base = baseForCCL();
		boolean loop = true;
		short pas[] = { 0, 0, 0, 0, 0, 0 };
		while (loop)
		{
			Population tmp_pop = new Population();

			for (int i = 0; i < ccl_base.size(); i++)
			{
				if (pas[i] == 0)
					tmp_pop.add(ccl_base.get(i));
				else if (pas[i] == 1)
					tmp_pop.add(ccl_base.get(i).permute());
			}
			// System.out.print("\n" + pas[0] + pas[1] + pas[2] + pas[3] +
			// pas[4]
			// + pas[5] + "  ");
			tmp_pop.display();
			loop = incrementCounterNAire(pas, 6, 3);
			if (!tmp_pop.isEmpty() && tmp_pop.isCircularCode2())
			{
				// System.out.print(" -> circulaire");
				circularCode.add(tmp_pop);
				result[tmp_pop.size() - 1]++;
			}
		}
		circularCode.quickSort();
		return result;
	}

	private boolean incrementCounterNAire(short[] t, int tsize, int mod)
	{
		int i = 0;
		while ((++t[i]) == mod)
		{
			t[i++] = 0;
			if (i == tsize)
				return false;
		}
		return true;
	}

	public int[] CCS()
	{
		int[] result = new int[6];
		circularCodeSelfComplementary.clear();
		for (int i = 0; i < circularCode.size(); i++)
		{

			circularCode.get(i).complementarity().display();
			// System.out.println("   -> " + i);
			if (circularCode.get(i).isSelfComplementary())
			{
				result[circularCode.get(i).size() - 1]++;
				// circularCode.get(i).display();
				// System.out.println("  -> auto complementaire.");
				circularCodeSelfComplementary.add(circularCode.get(i));
			}
		}

		return result;
	}

	public int[] CCM()
	{
		circularCodeMaximaux.clear();
		int result[] = new int[6];
		for (int i = 0; i < circularCode.size(); i++)
		{
			if (!circularCode.partialInclude(circularCode.get(i)))
			{
				circularCodeMaximaux.add(circularCode.get(i));
				result[circularCode.get(i).size() - 1]++;
				// circularCode.get(i).display();
				// System.out.println("  -> maximaux");
			}
		}
		return result;
	}

	public PopulationContainer getCircularCode()
	{
		return circularCode;
	}

	public void setCircularCode(PopulationContainer circularCode)
	{
		this.circularCode = circularCode;
	}

	public PopulationContainer getCircularCodeMaximaux()
	{
		return circularCodeMaximaux;
	}

	public void setCircularCodeMaximaux(PopulationContainer circularCodeMaximaux)
	{
		this.circularCodeMaximaux = circularCodeMaximaux;
	}

	public void setBase(Population base)
	{
		this.base = base;
	}

	public int[] CCMS()
	{
		circularCodeMaximauxSelfComplementary.clear();
		int result[] = new int[6];
		for (int i = 0; i < circularCodeMaximaux.size(); i++)
		{
			if (circularCodeMaximaux.get(i).isSelfComplementary())
			{
				result[circularCodeMaximaux.get(i).size() - 1]++;
				// circularCodeMaximaux.get(i).display();
				// System.out.println(" --> Maximaux et auto-complementaire");
				circularCodeMaximauxSelfComplementary.add(circularCodeMaximaux
						.get(i));
			}
		}
		return result;
	}

}
